package com.max.sportmanage.config.handler;

import com.alibaba.excel.annotation.write.style.OnceAbsoluteMerge;
import com.max.sportmanage.config.security.service.UserDetailServiceImpl;
import com.max.sportmanage.util.TokenUitl;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.cert.ocsp.Req;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;

/**
 * @program: java-sport-manage
 * @description:
 * @author: max-qaq
 * @create: 2021-10-23 23:55
 **/
@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    TokenUitl tokenUitl;

    @Autowired
    UserDetailServiceImpl userDetailsService;

    @Value("${jwt.tokenHeader}")
    String tokenHeader;

    @Value("${jwt.tokenHead}")
    String tokenHead;

    /**
     * 请求前获取请求头token
     */
    @Override
    protected void doFilterInternal(HttpServletRequest Request, HttpServletResponse Response, FilterChain filterChain) throws ServletException, IOException {
        //获取token头
        String tokenBody = Request.getHeader(tokenHeader);
        log.info("token全部"+tokenBody);
        //判断token是否存在
        if (null != tokenBody && tokenBody.startsWith(tokenHead)){
            //拿token主题
            String token = tokenBody.substring(tokenHead.length());
            log.info("获取token主体{}",token);
            //根据token获取用户名
            String userName = tokenUitl.getUserNameByToken(token);
            log.info("获取用户名成功");
            //token存在但是没登录信息
            if (null != userName && null == SecurityContextHolder.getContext().getAuthentication()){
                log.info("token存在但是没有登录信息");
                //没有登录信息，直接登录
                UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
                log.info("没有登录信息，直接登录");
                //判断token是否有效
                if(!tokenUitl.isExpiration(token) && userName.equals(userDetails.getUsername())){
                    //刷新security中用户信息
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
                    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(Request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                    log.info("刷新security中用户信息");
                }
            }
        }
        //过滤器放行
        filterChain.doFilter(Request,Response);
    }
}
